package com.example.pay.service.channel;

import com.example.pay.config.PayProperties;
import com.example.pay.dto.PrepayResponse;
import com.example.pay.entity.MemberOrder;
import com.example.pay.entity.MemberPackageItem;
import com.example.pay.util.RsaSignUtil;
import com.example.pay.util.PemUtil;
import com.example.pay.util.DateTimeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class AlipayPayService implements ChannelPayService {
    private final PayProperties properties;

    @Override
    public PrepayResponse prepay(MemberOrder order, MemberPackageItem item) {
        // 生成支付宝App支付orderString（简化版）
        Map<String, String> bizParams = new LinkedHashMap<>();
        bizParams.put("app_id", properties.getAlipay().getAppId());
        bizParams.put("method", "alipay.trade.app.pay");
        bizParams.put("format", "JSON");
        bizParams.put("charset", "utf-8");
        bizParams.put("sign_type", "RSA2");
        bizParams.put("timestamp", DateTimeUtil.alipayTimestampNow());
        bizParams.put("version", "1.0");
        bizParams.put("notify_url", properties.getAlipay().getNotifyUrl());
        // 业务参数
        String bizContent = String.format("{\"subject\":\"%s\",\"out_trade_no\":\"%s\",\"total_amount\":\"%s\",\"product_code\":\"QUICK_MSECURITY_PAY\"}",
            item.getItemDesc(), order.getOrderCode(), order.getPayAmount().toPlainString());
        bizParams.put("biz_content", bizContent);

        // 构造待签名字符串（按键名升序拼接）
        String contentToSign = bizParams.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(e -> e.getKey() + "=" + e.getValue())
                .collect(Collectors.joining("&"));

        String merchantPrivateKeyPem = PemUtil.loadPem(properties.getAlipay().getMerchantPrivateKey());
        String sign = RsaSignUtil.signSHA256withRSA(contentToSign, merchantPrivateKeyPem);

        // 生成orderString（URL编码）
        String orderString = bizParams.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(e -> e.getKey() + "=" + urlEncode(e.getValue()))
                .collect(Collectors.joining("&")) + "&sign=" + urlEncode(sign);

        Map<String, String> payload = new LinkedHashMap<>();
        payload.put("orderString", orderString);
        return new PrepayResponse("ALIPAY", order.getOrderCode(), payload, true);
    }

    private String urlEncode(String v) {
        try {
            return URLEncoder.encode(v, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return v;
        }
    }
}
